package com.weilan.ark3.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.weilan.ark3.common.Result;

import com.weilan.ark3.entity.*;
import com.weilan.ark3.entity.page.PageQuery;
import com.weilan.ark3.entity.page.TableDataInfo;
import com.weilan.ark3.mapper.ControlRtuMapper;
import com.weilan.ark3.service.ControlRtuService;
import com.weilan.ark3.service.TbDataService;
import com.weilan.ark3.service.TbSearchService;
import com.weilan.ark3.sqlite.SQLiteConfigUtils;
import com.weilan.ark3.sqlite.SqlUtil;
import com.weilan.ark3.utils.DateUtils;
import com.weilan.ark3.utils.StringUtils;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.sql.SQLException;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 数据查询
 */
@CrossOrigin
@RestController
@RequestMapping("weilan/system/air")
public class    TbSearchController {
    private static final Logger log = LoggerFactory.getLogger(TbSearchController.class);
    @Autowired
    private TbSearchService tbSearchService;

    @Autowired
    private ControlRtuService controlRtuService;

    @Autowired
    private TbDataService tbDataService;

    @Autowired
    private ExcelFaultController excelFaultController;

    @Autowired
    private ControlRtuMapper controlRtuMapper;

    @Value("${excel.outPut1}")
    private String excelOutPutPath;

    @ApiOperation(value = "根据表名、时间戳、deviceId获取数据")
    @PostMapping("list")
    public Result<List<Object>> listByTb(@RequestBody TableSearchBo tableSearchBo) {
//        List<Object> resultList = tbSearchService.listByTb(tableSearchBo);
//        return Result.success(resultList);
        return Result.success();
    }

    /**
     * 历史数据导出
     */
    @ApiOperation(value = "导出Excel")
    @PostMapping("/list/toExcel")

    public Result<String> listToExcel(@RequestBody ModuleSearchBo moduleSearchBo) {
        SqlUtil.deleteFilesInDirectory(excelOutPutPath);
        try {
            Thread.sleep(1500);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        //全部转换成小写
        moduleSearchBo.setModuleName(moduleSearchBo.getModuleName().toLowerCase());
        //查询module_name相符的配置
        List<TableDto> controlRtuList = tbDataService.list(new LambdaQueryWrapper<TableDto>()
                .eq(TableDto::getModuleName, moduleSearchBo.getModuleName()));

        //取出对应的表
        List<String> tbNameList = controlRtuList.stream()
                .map(TableDto::getInstructName).collect(Collectors.toList());

        String startTime = moduleSearchBo.getStartTime();
        // 解析日期时间字符串
        DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime dateTime = LocalDateTime.parse(startTime, inputFormatter);

        // 格式化为所需的输出格式
        DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        String formattedDate = dateTime.format(outputFormatter);
        //遍历集合给每个表名加上时间字符串
        List<String> newTbNameList = tbNameList.stream()
                .map(tbName -> tbName + "_" + formattedDate)
                .collect(Collectors.toList());
        StringBuffer sqlScript = new StringBuffer();
        String modeName = moduleSearchBo.getModuleName().toUpperCase() + moduleSearchBo.getDeviceId();
        String time = DateUtils.currentTimeNamingFile();
        sqlScript.append(".headers on\n" + ".mode csv\n" + ".output ");

        String format1 = MessageFormat.format("{0}/{1}.{2}.{3}.csv",
                excelOutPutPath,
                "historyData",
                modeName,
                time);
        sqlScript.append(format1 + "\n");
        String sqlStr = SqlUtil.generateSql(newTbNameList, moduleSearchBo.getDeviceId(), moduleSearchBo.getSlaveId(), moduleSearchBo.getStartTime(), moduleSearchBo.getEndTime());
        sqlScript.append(sqlStr);
        int result = SqlUtil.createScript(sqlScript.toString(), excelOutPutPath);
        if (result == 0) {
            return Result.fail();
        }
        String resultStr = MessageFormat.format("{0}.{1}.{2}.csv",
                "data/historyData",
                modeName,
                time);
        return Result.success(resultStr);
    }

    /**
     * 历史数据查询
     */
    @ApiOperation(value = "根据表名、时间戳、deviceId获取数据")
    @PostMapping("listByModule")

    public TableDataInfo<Object> listByModule(@RequestBody ModuleSearchBo moduleSearchBo, PageQuery pageQuery) throws SQLException {
        //全部转换为小写
        moduleSearchBo.setModuleName(moduleSearchBo.getModuleName().toLowerCase());
        //按照符合TableDto对象的数据存放到集合中
        List<TableDto> controlRtuList = tbDataService.list(new LambdaQueryWrapper<TableDto>().eq(TableDto::getModuleName, moduleSearchBo.getModuleName()));

        //取出对应的表
        List<String> tbNameList = controlRtuList.stream().map(TableDto::getInstructName).collect(Collectors.toList());

        String startTime = moduleSearchBo.getStartTime();
        // 解析日期时间字符串
        DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime dateTime = LocalDateTime.parse(startTime, inputFormatter);

        // 格式化为所需的输出格式
        DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        String formattedDate = dateTime.format(outputFormatter);
//        //遍历集合给每个表名加上时间字符串
        List<String> newTbNameList = tbNameList.stream().map(tbName -> tbName + "_" + formattedDate).collect(Collectors.toList());
//        //遍历表名，查看数据库是否有表,如果没有此表的话直接返回
//        if (newTbNameList.size() == 0) {
//            return TableDataInfo.build();
//        }
//        //查询当天日期的表如果其中一个表名没有则其他表也没有
//        String tbName = newTbNameList.get(0);
//        String table = tbSearchService.findTable(tbName);
//        if (table == null) {
//            return TableDataInfo.build();
//        } else {
        //表集合，开始时间，结束时间，查询条件
        return tbSearchService.listByModuleName(newTbNameList, moduleSearchBo.getDeviceId(), moduleSearchBo.getSlaveId(), moduleSearchBo.getStartTime(), moduleSearchBo.getEndTime(), pageQuery);
//        }
    }

    @ApiOperation(value = "根据模块名，设备id，日期查询")
    @PostMapping("breakdownByFind")
    public TableDataInfo<Object> listByBreakdown(@RequestBody ModuleSearchBo moduleSearchBo) {
        String startTime = moduleSearchBo.getStartTime();
        String endTime = moduleSearchBo.getEndTime();
        return tbSearchService.listByBreakdown(startTime, endTime);
    }

    @ApiOperation(value = "根据模块名，设备id，日期查询")
    @PostMapping("actionByFind")
    public TableDataInfo<Object> listByact(@RequestBody ModuleSearchBo moduleSearchBo) {
        String startTime = moduleSearchBo.getStartTime();
        String endTime = moduleSearchBo.getEndTime();
        return tbSearchService.listByact(startTime, endTime);
    }

    public int selectPvId() {
        return tbSearchService.selectPvId();
    }

    @ApiOperation(value = "编辑报文配置表")
    @PostMapping("/editControlTable")
    public Result<Object> editControlTable(@RequestBody List<BasicConfigDto> data) {
        //插入之前先将报文表和配置表清空。
        tbSearchService.deletecontrortu();
        tbSearchService.deletebasicconfig();
        int basic_ID = 1;
        for (BasicConfigDto datum : data) {
            datum.setId(basic_ID++);
            tbSearchService.insertAllbasic(datum);
        }
//        List<BasicConfigDto> basicConfigDtos = tbSearchService.selectAllbasic();
        //存放需要插入的所有报文
        List<ControlRtu> allmessge = new ArrayList<>();
        long id = 1;
        for (BasicConfigDto bcd : data) {
            int slaveId = bcd.getSlaveId();
            String com = bcd.getCom();
            Integer baud = bcd.getBaud();
            Map<String, Object> map = StringUtils.getAttributes(bcd);
            HashMap<Integer, Map<String, Object>> MAP = new HashMap<>();
            MAP.put(slaveId, map);
            // 遍历并处理Map
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                String key = entry.getKey();
                if (entry.getValue() instanceof String) {
                    continue;
                }
                Integer value = (Integer) entry.getValue();
                //获取电表的参数
                ConfigDto configDto = SQLiteConfigUtils.query();
                String ammeterType = configDto.getAmmeterType();
                List<ControlRtu> messge = tbSearchService.findAllmessge(key, value + 1);
                for (ControlRtu controlRtu : messge) {
                    if (controlRtu.getModuleName().equals("ammeter") && !controlRtu.getRemark().equals(ammeterType)) {
                        continue;
                    }
                    controlRtu.setSlaveId(slaveId);
                    controlRtu.setComName(com);
                    controlRtu.setBaudRate(baud);
                    allmessge.add(controlRtu);
                }
            }
        }
        // 分组根据 slaveId
        Map<Integer, List<ControlRtu>> groupedBySlaveId = allmessge.stream()
                .collect(Collectors.groupingBy(ControlRtu::getSlaveId));
        // 获取所有不同的 slaveId
        List<Integer> slaveIds = new ArrayList<>(groupedBySlaveId.keySet());
        // 如果需要按照某种顺序排序 slaveIds，可以使用 Collections.sort(slaveIds) 或其他方法
        List<ControlRtu> allmessgeShuffled = new ArrayList<>();
        // 循环插入，保持交叉顺序
        int index = 0;
        while (!groupedBySlaveId.isEmpty()) {
            Integer slaveId = slaveIds.get(index);
            List<ControlRtu> list = groupedBySlaveId.get(slaveId);
            if (list != null && !list.isEmpty()) {
                allmessgeShuffled.add(list.remove(0)); // 将该组中的第一个元素加入结果集
                if (list.isEmpty()) {
                    groupedBySlaveId.remove(slaveId); // 如果该组已经空了，则从 Map 中移除
                }
            }
            index = (index + 1) % slaveIds.size(); // 循环递增索引
        }
        for (ControlRtu controlRtu : allmessgeShuffled) {
            controlRtu.setId(id++);
            tbSearchService.saveConfig(controlRtu);
        }
        return Result.success(new ArrayList<>());
    }

    @ApiOperation(value = "查询报文配置表")
    @GetMapping("/selectControlTable")
    public Result<Object> selectControlTable() {
        List<BasicConfigDto> basicConfigDtos = tbSearchService.selectAllbasic();
        return Result.success(basicConfigDtos);
    }

    @ApiOperation(value = "编辑配置表")
    @PostMapping("/editConfig")
    public Result<Object> editConfig(@RequestBody ConfigDto configDto) {
        SQLiteConfigUtils.update(configDto);
        return Result.success(new ArrayList<>());
    }

    @ApiOperation(value = "查询配置表")
    @GetMapping("/selectConfig")
    public Result<ConfigDto> selectConfig() {
        ConfigDto data = SQLiteConfigUtils.query();
        return Result.success(data);
    }

    @ApiOperation(value = "查询曲线图")
    @PostMapping("/selectSocPower")
    public List<Map<String, Object>> selectSocPower(@RequestBody List<String> addr, @RequestParam String date) {
        List<String> nameList = controlRtuMapper.selectAddrToName(addr);
        nameList.add("date");
        // 定义输入日期格式
        DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 定义输出日期格式
        DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        // 解析输入日期
        LocalDate objectResult = LocalDate.parse(date, inputFormatter);
        // 格式化为输出日期格式
        String outputDate = objectResult.format(outputFormatter);
        String tableName = "ems_info_" + outputDate;
        return tbSearchService.selectSocPower(nameList, tableName);
    }

}
